<?php

namespace addons\cardocr\library;

use fast\Http;
use think\Config;
use think\addons\Controller;
use TencentCloud\Common\Credential;
use TencentCloud\Common\Profile\ClientProfile;
use TencentCloud\Common\Profile\HttpProfile;
use TencentCloud\Common\Exception\TencentCloudSDKException;
use TencentCloud\Ocr\V20181119\OcrClient;
use TencentCloud\Ocr\V20181119\Models\IDCardOCRRequest;
use TencentCloud\Faceid\V20180301\FaceidClient;
use TencentCloud\Faceid\V20180301\Models\IdCardOCRVerificationRequest;
use think\Session;
use app\common\model\User;
use think\Exception;

class Card
{

    /**
     * @param string $idnum  身份证id
     * @param string $name   姓名
     * @param string $ImageBase64  身份证正面base64
     * @param string $ImageUrl     身份证正面绝对url,必须公网可访问的
     * @return array|mixed
     */
    public static function checkidcard($idnum="", $name="", $ImageBase64 = "", $ImageUrl = "")
    {
        $card_config = get_addon_config('cardocr');
        $secretId = $card_config['secretid'];
        $secretKey = $card_config['secretkey'];
        $endpoint = $card_config['endpoint'];
        $region = $card_config['region'];

        try {
            $data = array();
            $data["IdCard"] = $idnum;
            $data['Name'] = $name;
            $data['ImageBase64'] = $ImageBase64;
            $data['ImageUrl'] = $ImageUrl;

            $cred = new Credential($secretId, $secretKey);
            $httpProfile = new HttpProfile();
            $httpProfile->setEndpoint($endpoint);

            $clientProfile = new ClientProfile();
            $clientProfile->setHttpProfile($httpProfile);
            $client = new FaceidClient($cred, $region, $clientProfile);

            $req = new IdCardOCRVerificationRequest();

            $params = json_encode($data);
            $req->fromJsonString($params);


            $resp = $client->IdCardOCRVerification($req);

            $params_data = json_decode($resp->toJsonString(), true);

            return $params_data;

            // var_dump( json_decode($resp->toJsonString(), true));

            // print_r($resp->toJsonString());
        } catch (TencentCloudSDKException $e) {
            return array("code" => $e->getErrorCode(), "msg" => $e->getMessage(), "data" => "");
        }
    }

    /**
     * @param json $params ImageBase64格式
     * @param string $status|'FRONT','BACK' 识别身份证正反
     * @return array|mixed
     */
    public static function checkcardocr($params, $status = 'FRONT')
    {
        $card_config = get_addon_config('cardocr');
        $secretId = $card_config['secretid'];
        $secretKey = $card_config['secretkey'];
        $endpoint = $card_config['endpoint_ocr'];
        $region = $card_config['region'];
        $cardside['FRONT'] = "身份证正面";
        $cardside['BACK'] = "身份证反面";
        try {
            $cred = new Credential($secretId, $secretKey);
            $httpProfile = new HttpProfile();
            $httpProfile->setEndpoint($endpoint);

            $clientProfile = new ClientProfile();
            $clientProfile->setHttpProfile($httpProfile);
            $client = new OcrClient($cred, $region, $clientProfile);
            $req = new IDCardOCRRequest();
            $req->fromJsonString($params);
            $resp = $client->IDCardOCR($req);
            return  json_decode($resp->toJsonString(), true);
        } catch (TencentCloudSDKException $e) {
            return array("code" => $e->getErrorCode(), "msg" => $cardside[$status] . $e->getMessage(), "data" => "");
        }
    }

    /**
     * @param $image_file   图片url绝对地址
     * @return array|string
     */
    public static function base64EncodeImage($image_file)
    {
        try {
            $base64_image=self::geturlbase64($image_file, 2);
            return !empty($base64_image['data']) ?$base64_image['data']:"";
        } catch (Exception $exception) {
            return array("code" => 0, "msg" => $exception->getMessage());
        }
    }

    /**
     * 将一个字符串部分字符用$re替代隐藏
     * @param string $string 待处理的字符串
     * @param int $start 规定在字符串的何处开始，
     *                            正数 - 在字符串的指定位置开始
     *                            负数 - 在从字符串结尾的指定位置开始
     *                            0 - 在字符串中的第一个字符处开始
     * @param int $length 可选。规定要隐藏的字符串长度。默认是直到字符串的结尾。
     *                            正数 - 从 start 参数所在的位置隐藏
     *                            负数 - 从字符串末端隐藏
     * @param string $re 替代符
     * @return string   处理后的字符串
     */
    public static function hidestr($string, $start = 0, $length = 0, $re = '*')
    {
        if (empty($string)) {
            return false;
        }
        $strarr = array();
        $mb_strlen = mb_strlen($string);
        while ($mb_strlen) {//循环把字符串变为数组
            $strarr[] = mb_substr($string, 0, 1, 'utf8');
            $string = mb_substr($string, 1, $mb_strlen, 'utf8');
            $mb_strlen = mb_strlen($string);
        }
        $strlen = count($strarr);
        $begin = $start >= 0 ? $start : ($strlen - abs($start));
        $end = $last = $strlen - 1;
        ;
        if ($length > 0) {
            $end = $begin + $length - 1;
        } elseif ($length < 0) {
            $end -= abs($length);
        }
        for ($i = $begin; $i <= $end; $i++) {
            $strarr[$i] = $re;
        }
        // if ($begin >= $end || $begin >= $last || $end > $last) return false;
        return implode('', $strarr);
    }

    /**
     * @param $url
     * @param int $type  0普通数据 2获取base64
     * @param int $timeout
     * @return array
     */
    public static function geturlbase64($url, $type=0, $timeout=30)
    {
        $msg = ['code'=>2100,'status'=>'error','msg'=>'未知错误！'];
        $imgs= ['image/jpeg'=>'jpeg',
            'image/jpg'=>'jpg',
            'image/gif'=>'gif',
            'image/png'=>'png',
            'text/html'=>'html',
            'text/plain'=>'txt',
            'image/pjpeg'=>'jpg',
            'image/x-png'=>'png',
            'image/x-icon'=>'ico'
        ];
        if (!stristr($url, 'http')) {
            $msg['code']= 2101;
            $msg['msg'] = 'url地址不正确!';
            return $msg;
        }
        $dir= pathinfo($url);
        $host = $dir['dirname'];
        $refer= $host.'/';
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_REFERER, $refer); //伪造来源地址
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//返回变量内容还是直接输出字符串,0输出,1返回内容
        curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);//在启用CURLOPT_RETURNTRANSFER的时候，返回原生的（Raw）输出
        curl_setopt($ch, CURLOPT_HEADER, 0); //是否输出HEADER头信息 0否1是
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); //超时时间
        $data = curl_exec($ch);
        //$httpCode = curl_getinfo($ch,CURLINFO_HTTP_CODE);
        //$httpContentType = curl_getinfo($ch,CURLINFO_CONTENT_TYPE);
        $info = curl_getinfo($ch);
        curl_close($ch);
        $httpCode = intval($info['http_code']);
        $httpContentType = $info['content_type'];
        $httpSizeDownload= intval($info['size_download']);

        if ($httpCode!='200') {
            $msg['code']= 2102;
            $msg['msg'] = 'url返回内容不正确！';
            return $msg;
        }
        if ($type>0 && !isset($imgs[$httpContentType])) {
            $msg['code']= 2103;
            $msg['msg'] = 'url资源类型未知！';
            return $msg;
        }
        if ($httpSizeDownload<1) {
            $msg['code']= 2104;
            $msg['msg'] = '内容大小不正确！';
            return $msg;
        }
        $msg['code']  = 200;
        $msg['status']='success';
        $msg['msg']   = '资源获取成功';
        if ($type==0 or $httpContentType=='text/html') {
            $msg['data'] = $data;
        }
        $base_64 = base64_encode($data);
        if ($type==1) {
            $msg['data'] = $base_64;
        } elseif ($type==2) {
            $msg['data'] = "data:{$httpContentType};base64,{$base_64}";
        } elseif ($type==3) {
            $msg['data'] = "<img src='data:{$httpContentType};base64,{$base_64}' />";
        } else {
            $msg['msg'] = '未知返回需求！';
        }
        unset($info,$data,$base_64);
        return $msg;
    }
}
